package com.rdtravel.entities;

import com.rdtravel.valueobjects.CreditCard;
import com.rdtravel.valueobjects.WayOfPayment;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;

import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.NumberFormat.Style;

@Entity
@Table(name = "bookings")
public class Booking implements Serializable {
	private static final long serialVersionUID = 1L;
	private static final BigDecimal HUNDRED = new BigDecimal(100);
	@Id
	@GeneratedValue
	private long id;
	@ManyToOne
	@JoinColumn(name = "tripid")
	private Trip trip;
	@ManyToOne
	@JoinColumn(name = "customerid")
	private Customer customer;
	@Min(1)
	private int seats;
	@NotNull
	@Enumerated(EnumType.ORDINAL)
	private WayOfPayment wayOfPayment;
	@NumberFormat(style = Style.NUMBER)
	private BigDecimal grossPricePerPerson;	
	private int creditcardDiscountPercentage;
	@Embedded
	@Valid
	private CreditCard creditCard;

	public WayOfPayment getWayOfPayment() {
		return wayOfPayment;
	}

	public void setWayOfPayment(WayOfPayment wayOfPayment) {
		this.wayOfPayment = wayOfPayment;
		if (wayOfPayment != WayOfPayment.CREDITCARD) {
			creditCard = null;
		}
	}

	public BigDecimal getGrossPricePerPerson() {
		return grossPricePerPerson;
	}

	public void setGrossPricePerPerson(BigDecimal grossPricePerPerson) {
		this.grossPricePerPerson = grossPricePerPerson;
	}

	@NumberFormat(style = Style.NUMBER)
	public BigDecimal getNetPricePerPerson() {
		BigDecimal netPricePerPerson = grossPricePerPerson;
		if (wayOfPayment != null
				&& wayOfPayment.equals(WayOfPayment.CREDITCARD)) {
		    BigDecimal factor = BigDecimal.ONE.subtract(new BigDecimal(creditcardDiscountPercentage).divide(HUNDRED));
		    	    netPricePerPerson = netPricePerPerson.multiply(factor).setScale(2, RoundingMode.HALF_UP);
		}
		return netPricePerPerson;
	}

	@NumberFormat(style = Style.NUMBER)
	public BigDecimal getNetPrice() {
		return getNetPricePerPerson().multiply(new BigDecimal(seats));
	}

	@NumberFormat(style = Style.NUMBER)
	public BigDecimal getGrossPrice() {
		return getGrossPricePerPerson().multiply(new BigDecimal(seats));
	}

	@NumberFormat(style = Style.NUMBER)
	public int getCreditcardDiscountPercentage() {
		return creditcardDiscountPercentage;
	}

	public void setCreditcardDiscountPercentage(
			int creditcardDiscountPercentage) {
		this.creditcardDiscountPercentage = creditcardDiscountPercentage;
	}

	public long getId() {
		return id;
	}

	public Trip getTrip() {
		return trip;
	}

	public void setTrip(Trip trip) {
		this.trip = trip;
	}

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}

	public int getSeats() {
		return seats;
	}

	public void setSeats(int seats) {
		this.seats = seats;
	}

	public CreditCard getCreditCard() {
		return creditCard;
	}

	public void setCreditCard(CreditCard creditCard) {
		this.creditCard = creditCard;
	}

	@Override
	public String toString() {
		return "Booking [id=" + id + ", seats=" + seats + "]";
	}

}
